#include "EventLoop.hpp"
#include "TcpServer.hpp"
#include "Threadpool.hpp"

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using std::cout;
using std::endl;


class MyTask
{
public:
    MyTask(const string & msg, wd::TcpConnectionPtr conn)
    : _msg(msg)
    , _conn(conn)
    {}
    
    void process()
    {   
        cout << "task is processing.\n" << endl;
        //process方法的运行在线程池中的某一个线程(计算线程, 有多个)
        //decode
        //compute
        //encode
        //
        //假设以下的就是要发送给对端的消息
        string response = _msg;
        //执行消息的发送
        //conn->send(response);//这种做法是在计算线程中完成数据的发送
        //这样没有做到职责分离
        //
        //这里正确的做法应该是计算线程要通知IO线程进行消息的发送
        //wakeup();//唤醒之后，让IO线程完成数据的发送
        _conn->sendInLoop(response);
    }

private:
    string _msg;
    wd::TcpConnectionPtr _conn;
};

wd::Threadpool * gThreadpool = nullptr;

void onConnection(wd::TcpConnectionPtr conn)
{
    //获取连接的信息
    cout << conn->toString() << " has connected.\n";
}

void onMessage(wd::TcpConnectionPtr conn)
{
    //消息到达时的处理方式
    //cout << "recv msg: " << conn->receive() << endl;
    //conn->send("welecome to server.");
    //获取到消息之后，对消息进行业务逻辑的处理
    //对于单个Reactor来说，业务逻辑的处理时间不宜过长，
    //如果时间过长，会影响其他fd的响应时间
    //比如说现在同时有100个连接要进行处理，希望在1秒钟内处理完毕
    //则每个连接的处理需要在10ms之内完成
    //
    //如果单个连接的处理了做不到这么快，那应该怎么办？
    //解决方案：将获取到的消息封装成一个任务,交给线程池来进行处理
    string msg = conn->receive();
    cout << "msg:" << msg << endl;
    MyTask task(msg, conn);
    gThreadpool->addTask(std::bind(&MyTask::process, task));
}

void onClose(wd::TcpConnectionPtr conn)
{
    //连接断开时的处理
    cout << conn->toString() << " has closed.\n";
}

 
int main(void)
{
    wd::Threadpool threadpool(4, 10);
    threadpool.start();
    gThreadpool = &threadpool;//全局的指针指向threadpool对象

    wd::TcpServer server("192.168.30.129", 8000);
    server.setAllCallbacks(onConnection,
                         onMessage,
                         onClose);
    server.start();//开始事件循环
	return 0;
}
